package top.blueShark.template.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.blueShark.template.entity.SysUser;
import top.blueShark.template.entity.dto.SysUserRequestDTO;
import top.blueShark.template.mapper.SysUserMapper;
import top.blueShark.template.service.SysUserService;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 系统用户服务实现类
 */
@Service
public class SysUserServiceImpl implements SysUserService {

	@Autowired
	private SysUserMapper sysUserMapper;
	
	@Value("${app.default-roles.user-id}") // 从 application.yml 读取值
	private String defaultUserRoleId; // 将常量改为成员变量

	@Override
	@Transactional(rollbackFor = Exception.class)
	public SysUser register(SysUser user) {
		// 检查用户名是否已存在
		SysUser existingUser = sysUserMapper.findByUsername(user.getUsername());
		if (existingUser != null) {
			throw new RuntimeException("用户名已存在");
		}
		// 检查手机号是否已存在（可选，建议加上）
		if (user.getPhone() != null && sysUserMapper.findByPhone(user.getPhone()) != null) {
			throw new RuntimeException("手机号已存在");
		}
		// 设置默认值
		user.setStatus(1);
		LocalDateTime now = LocalDateTime.now();
		user.setCreateTime(now);
		user.setUpdateTime(now);

		// 保存用户
		sysUserMapper.insert(user);

        // 新增：注册成功后，为新用户分配默认的 'user' 角色
        if (user.getId() != null) {
            // 确保 DEFAULT_USER_ROLE_ID 存在于数据库中（由RoleInitializer保证）
            sysUserMapper.insertUserRoles(user.getId(), Arrays.asList(defaultUserRoleId));
        } else {
            // 这是一个不太可能发生的情况，如果 mybatis 的 useGeneratedKeys 配置正确
            throw new RuntimeException("User ID is null after insert, cannot assign default role.");
        }

		return user;
	}

	@Override
	public SysUser findByUsername(String username) {
		return sysUserMapper.findByUsername(username);
	}

	@Override
    public List<SysUser> getAll(SysUserRequestDTO sysUserRequestDTO) {
		Integer offset = (sysUserRequestDTO.getPage() - 1) * sysUserRequestDTO.getPageSize();
		sysUserRequestDTO.setPage(offset);
        List<SysUser> users = sysUserMapper.selectAll(sysUserRequestDTO);
        // 遍历所有用户，为每个用户加载角色信息
        for (SysUser user : users) {
            List<String> roleNames = sysUserMapper.selectRoleNamesByUserId(user.getId());
            user.setRoles(roleNames); // 假设 SysUser 类有 setRoles 方法来设置角色列表
        }
        return users;
    }

	@Override
	public SysUser getById(Long id) {
		return sysUserMapper.selectById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class) // 添加事务注解
	public int update(SysUser user) {
		user.setUpdateTime(LocalDateTime.now());
		int effect = sysUserMapper.update(user); // 更新用户信息
		// TODO 更新用户角色信息
		// 1. 如果传入了新的角色列表，则添加新角色
		if (user.getRoles() != null && !user.getRoles().isEmpty()) {
			// 先删除用户原有的所有角色
			sysUserMapper.deleteUserRoles(user.getId());
			sysUserMapper.insertUserRoles(user.getId(), user.getRoles());
		}
		return effect;
	}

	@Override
	public void delete(Long id) {
		// 1. 删除用户关联的角色信息
		sysUserMapper.deleteUserRoles(id); // 确保在删除用户前，先删除关联的角色

		// 2. 物理删除用户
		sysUserMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class) // 确保 add 方法也是事务性的
	public void add(SysUser user) {
		user.setCreateTime(LocalDateTime.now());
		user.setUpdateTime(LocalDateTime.now());
		user.setPassword("123456");
		if (StringUtils.isEmpty(user.getRealName())){
			user.setRealName(UUID.randomUUID().toString());
		}
		sysUserMapper.insert(user); // user.getId() 会在此处通过 useGeneratedKeys 回填

		// 处理新增用户的角色
		List<String> rolesToAssign = user.getRoles();

		// 如果前端没有传递角色 (rolesToAssign 为 null 或空列表)，则可以考虑分配默认角色
		// 如果前端传递了角色，则使用前端传递的角色
		// 注意：如果业务逻辑是：即使前端传递了空数组也表示不分配任何角色（而不是分配默认角色），则需要调整此逻辑
		if (rolesToAssign == null || rolesToAssign.isEmpty()) {
			// 示例：如果需要，在这里设置默认角色。如果不需要默认角色，则此 if 块可以移除或注释掉。
			// rolesToAssign = List.of("user"); // 假设 "user" 是一个有效的角色ID
		}

		// 只有当 rolesToAssign 列表确实有内容时，才进行插入操作
		if (rolesToAssign != null && !rolesToAssign.isEmpty()) {
			// 确保 user.getId() 此时有值
			if (user.getId() == null) {
				// 这是一个不太可能发生的情况，如果 mybatis 的 useGeneratedKeys 配置正确
				throw new RuntimeException("User ID is null after insert, cannot assign roles.");
			}
			sysUserMapper.insertUserRoles(user.getId(), rolesToAssign);
		}
	}

	@Override
	public SysUser findByPhone(String phone) {
		return sysUserMapper.findByPhone(phone);
	}

	@Override
	public void assignRoles(Long userId, List<String> roleIds) {
		// 先删除原有角色
		sysUserMapper.deleteUserRoles(userId);
		// 再插入新角色
		if (roleIds != null && !roleIds.isEmpty()) {
			sysUserMapper.insertUserRoles(userId, roleIds);
		}
	}

	@Override
	public long getTotalUserCount() {
		return sysUserMapper.countTotalUsers();
	}

	// 新增的方法实现
	@Override
	public List<String> getRoleIdsByUserId(Long userId) {
		return sysUserMapper.selectRoleIdsByUserId(userId); // 假设 SysUserMapper 中有这个方法
	}

	@Override
	public List<String> getRoleNamesByUserId(Long userId) {
		return sysUserMapper.selectRoleNamesByUserId(userId);
	}

	  // 实现新增方法：根据用户ID获取其关联的所有菜单的权限码
	  @Override
	  public List<String> getAuthCodesByUserId(Long userId) {
		  return sysUserMapper.selectAuthCodesByUserId(userId);
	  }
}